// 高级 axios 配置示例
import axios from 'axios'
import { ElMessage } from 'element-plus'

// 1. 重复请求取消机制
const pendingRequests = new Map()

const generateRequestKey = (config) => {
  const { method, url, params, data } = config
  return [method, url, JSON.stringify(params), JSON.stringify(data)].join('&')
}

const addPendingRequest = (config) => {
  const requestKey = generateRequestKey(config)
  config.cancelToken = config.cancelToken || new axios.CancelToken((cancel) => {
    if (!pendingRequests.has(requestKey)) {
      pendingRequests.set(requestKey, cancel)
    }
  })
}

const removePendingRequest = (config) => {
  const requestKey = generateRequestKey(config)
  if (pendingRequests.has(requestKey)) {
    const cancelToken = pendingRequests.get(requestKey)
    cancelToken('请求被取消')
    pendingRequests.delete(requestKey)
  }
}

// 2. 请求重试机制
const retryRequest = async (error, retryCount = 3) => {
  const { config } = error
  
  if (!config || !retryCount) {
    return Promise.reject(error)
  }
  
  config.__retryCount = config.__retryCount || 0
  
  if (config.__retryCount >= retryCount) {
    return Promise.reject(error)
  }
  
  config.__retryCount += 1
  
  // 延迟重试
  const delay = new Promise(resolve => {
    setTimeout(resolve, 1000 * config.__retryCount)
  })
  
  await delay
  
  return axios(config)
}

// 3. 文件上传进度监控
export const uploadWithProgress = (url, formData, onProgress) => {
  return axios.post(url, formData, {
    headers: {
      'Content-Type': 'multipart/form-data'
    },
    onUploadProgress: (progressEvent) => {
      if (onProgress) {
        const percentCompleted = Math.round(
          (progressEvent.loaded * 100) / progressEvent.total
        )
        onProgress(percentCompleted)
      }
    }
  })
}

// 4. 请求队列管理
class RequestQueue {
  constructor() {
    this.queue = []
    this.processing = false
  }
  
  add(request) {
    return new Promise((resolve, reject) => {
      this.queue.push({
        request,
        resolve,
        reject
      })
      this.process()
    })
  }
  
  async process() {
    if (this.processing || this.queue.length === 0) {
      return
    }
    
    this.processing = true
    
    while (this.queue.length > 0) {
      const { request, resolve, reject } = this.queue.shift()
      
      try {
        const result = await request()
        resolve(result)
      } catch (error) {
        reject(error)
      }
      
      // 添加延迟避免请求过于频繁
      await new Promise(resolve => setTimeout(resolve, 100))
    }
    
    this.processing = false
  }
}

export const requestQueue = new RequestQueue()

// 5. 缓存机制
const cache = new Map()
const CACHE_EXPIRE_TIME = 5 * 60 * 1000 // 5分钟

export const cachedRequest = async (url, params, expireTime = CACHE_EXPIRE_TIME) => {
  const cacheKey = `${url}?${JSON.stringify(params)}`
  const cached = cache.get(cacheKey)
  
  if (cached && Date.now() - cached.timestamp < expireTime) {
    return cached.data
  }
  
  try {
    const response = await axios.get(url, { params })
    cache.set(cacheKey, {
      data: response.data,
      timestamp: Date.now()
    })
    return response.data
  } catch (error) {
    throw error
  }
}

// 6. 请求/响应数据转换
export const transformRequest = (data) => {
  // 请求数据转换
  if (data && typeof data === 'object') {
    // 移除空值
    Object.keys(data).forEach(key => {
      if (data[key] === null || data[key] === undefined || data[key] === '') {
        delete data[key]
      }
    })
  }
  return data
}

export const transformResponse = (data) => {
  // 响应数据转换
  if (data && typeof data === 'object') {
    // 日期字符串转Date对象
    if (data.createdAt && typeof data.createdAt === 'string') {
      data.createdAt = new Date(data.createdAt)
    }
    if (data.updatedAt && typeof data.updatedAt === 'string') {
      data.updatedAt = new Date(data.updatedAt)
    }
  }
  return data
}

// 7. 错误分类处理
export const handleError = (error) => {
  if (axios.isCancel(error)) {
    console.log('请求被取消:', error.message)
    return
  }
  
  if (error.response) {
    // 服务器响应错误
    const { status, data } = error.response
    switch (status) {
      case 400:
        ElMessage.error('请求参数错误')
        break
      case 401:
        ElMessage.error('未授权，请重新登录')
        break
      case 403:
        ElMessage.error('禁止访问')
        break
      case 404:
        ElMessage.error('请求的资源不存在')
        break
      case 500:
        ElMessage.error('服务器内部错误')
        break
      default:
        ElMessage.error(data?.message || `请求失败 (${status})`)
    }
  } else if (error.request) {
    // 网络错误
    ElMessage.error('网络连接失败，请检查网络设置')
  } else {
    // 其他错误
    ElMessage.error(error.message || '请求失败')
  }
}

// 8. 使用示例
export const advancedExamples = {
  // 带重试的请求
  async requestWithRetry(url, params, retryCount = 3) {
    try {
      return await axios.get(url, { params })
    } catch (error) {
      return retryRequest(error, retryCount)
    }
  },
  
  // 带进度的文件上传
  async uploadFile(file, onProgress) {
    const formData = new FormData()
    formData.append('file', file)
    
    return uploadWithProgress('/api/upload', formData, onProgress)
  },
  
  // 队列请求
  async queuedRequest(url, params) {
    return requestQueue.add(() => axios.get(url, { params }))
  },
  
  // 缓存请求
  async cachedGet(url, params) {
    return cachedRequest(url, params)
  }
}

// 9. 导出工具函数
export {
  addPendingRequest,
  removePendingRequest,
  retryRequest,
  RequestQueue
} 